/*
 * ============================================================================
 *
 *       Filename:  main.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2017年08月08日 11时17分31秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "report_tcp.h"

#define SERPORT		(6666)

int main(int argc, char *argv[])
{
	int serfd, clifd;
	struct sockaddr_in seraddr, cliaddr;

	serfd = socket(AF_INET, SOCK_STREAM, 0);
	if(serfd < 0) {
		fprintf(stderr, "Socket failed: %s(%d)\n",
			strerror(errno), errno);
		exit(1);
	}

	memset(&seraddr, 0, sizeof(seraddr));
	seraddr.sin_family = AF_INET;
	seraddr.sin_addr.s_addr = INADDR_ANY;
	seraddr.sin_port = htons(SERPORT);

	if(bind(serfd, (void *)&seraddr, sizeof(seraddr)) < 0) {
		fprintf(stderr, "Bind failed: %s(%d)\n",
			strerror(errno), errno);
		exit(1);
	}

	if(listen(serfd, 0) < 0) {
		fprintf(stderr, "Listen failed: %s(%d)\n",
			strerror(errno), errno);
		exit(1);
	}


	socklen_t addrlen = sizeof(cliaddr);
	clifd = accept(serfd, (void *)&cliaddr, &addrlen);
	if(clifd < 0) {
		fprintf(stderr, "Accept failed: %s(%d)\n", 
			strerror(errno), errno);
		exit(1);
	}

	printf("Get client: %s, %d\n", 
		inet_ntoa(cliaddr.sin_addr),
		ntohs(cliaddr.sin_port));

	char buf[2048];
	char *data;
	struct tcphead_t *head;
	char pktlen[5] = {0};
	char func[3] = {0};
	char seqnum[5] = {0};

	while(1) {
		printf("=============================================================\n");
		/* recv header */
		if(recv(clifd, buf, sizeof(struct tcphead_t), 0) <= 0) {
			fprintf(stderr, "Recv failed: %s(%d)\n",
				strerror(errno), errno);
			exit(2);
		}

		head = (void *)buf;
		memcpy(pktlen, head->pktlen, 4);
		memcpy(func, head->func, 2);
		memcpy(seqnum, head->seqnum, 4);
		data = head->data;
		printf("\ttcphead: \n\t\tpktlen: %s, func: %s, seqnum: %s\n", 
			pktlen, func, seqnum);

		int left = atoi(pktlen) - sizeof(struct tcphead_t);
		if(recv(clifd, data, left, 0) <= 0) {
			fprintf(stderr, "Recv failed: %s(%d)\n",
				strerror(errno), errno);
			exit(2);
		}

		if(strncmp(func, WIFI_HEARTBEAT, 2) == 0) {
			if(left != sizeof(struct heartbeat_t)) {
				fprintf(stderr, "heartbeat malformat\n");
				exit(3);
			}
			struct heartbeat_t *hb = (void *)(head->data);
			char devmac[18] = {0};
			memcpy(devmac, hb->devmac, 17);
			printf("\thearbeat: %s\n", devmac);

			struct timesync_t *cur = (void *)(head->data);
			int sendsize = sizeof(struct tcphead_t) + 
				sizeof(struct timesync_t);
			sprintf(head->pktlen, "%04d", sendsize);
			snprintf(cur->curr, 15, "20170101120702");

			if(send(clifd, buf, sendsize, 0) < 0) {
				fprintf(stderr, "Sendd failed: %s(%d)\n",
					strerror(errno), errno);
				exit(3);
			}
		} else if(strncmp(func, WIFI_AP_DATA, 2) == 0) {
			if(left != sizeof(struct aprep_t)) {
				fprintf(stderr, "ap report malformat\n");
				exit(3);
			}

			struct aprep_t *ap = (void *)(head->data);
			char devmac[18] = {0};
			char repnum[3] = {0};
			char apmac[18] = {0};
			char ssid[65] = {0};
			char channel[3] = {0};
			char encrypt[11] = {0};
			char signal[5] = {0};

			memcpy(devmac, ap->devmac, 17);
			memcpy(repnum, ap->repnum, 2);
			memcpy(apmac, ap->apmac, 17);
			memcpy(ssid, ap->ssid, 64);
			memcpy(channel, ap->channel, 2);
			memcpy(encrypt, ap->encrypt, 10);
			memcpy(signal, ap->signal, 4);
			printf("\tap:\n\t\tdevmac: %s\n\t\trepnum: %s\n\t\tapmac: %s\n\t\tssid: %s\n\t\t"
				"channel: %s\n\t\tencrypt: %s\n\t\tsignal:%s\n",
				devmac, repnum, apmac, ssid, channel, encrypt, signal);

			struct resp_t *resp = (void *)(head->data);
			int sendsize = sizeof(struct tcphead_t) + 
				sizeof(struct resp_t);
			sprintf(head->pktlen, "%04d", sendsize);
			snprintf(resp->status, 1, "1");

			if(send(clifd, buf, sendsize, 0) < 0) {
				fprintf(stderr, "Sendd failed: %s(%d)\n",
					strerror(errno), errno);
				exit(3);
			}
		} else if(strncmp(func, WIFI_CLI_DATA, 2) == 0) {

			struct resp_t *resp = (void *)(head->data);
			int sendsize = sizeof(struct tcphead_t) + 
				sizeof(struct resp_t);
			sprintf(head->pktlen, "%04d", sendsize);
			snprintf(resp->status, 1, "1");

			if(send(clifd, buf, sendsize, 0) < 0) {
				fprintf(stderr, "Sendd failed: %s(%d)\n",
					strerror(errno), errno);
				exit(3);
			}
		}
	}
}
